package git.soulbgm.service.impl;

import git.soulbgm.mapper.RoleMenuMapper;
import git.soulbgm.pojo.*;
import git.soulbgm.service.*;
import git.soulbgm.utils.ClassUtil;
import git.soulbgm.utils.ObjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

/**
 * @author SoulBGM
 * @version 1.0
 * @date 2019/10/31 16:22
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleMenuMapper roleMenuMapper;

    @Override
    public UserDto findByUsername(String username) {
        User userCond = new User();
        userCond.setUsername(username);
        User user = userService.findOne(userCond);
        UserDto dto = new UserDto();
        // 如果字段名称和UserDto的字段名称一致可以使用克隆来拷贝对象
        // 如果字段名称和UserDto的字段名称不一致则需要一个一个进行赋值
        ClassUtil.copyClass(user, dto);
        return dto;
    }

    @Override
    public List<RoleDto> findRoleByUserId(Serializable userId) {
        try {
            UserRole userRoleCond = new UserRole();
            userRoleCond.setUserId((Integer) userId);
            List<UserRole> userRoleList = userRoleService.findByModel(userRoleCond);
            String roleIds = ObjectUtil.getFieldStr(userRoleList, "roleId");
            List<Role> roleList = roleService.findByIds(roleIds);
            return getRoleDtoList(roleList);
        } catch (NoSuchFieldException e) {
            return null;
        }
    }

    private List<RoleDto> getRoleDtoList(List<Role> roleList) {
        List<RoleDto> dtoList = new ArrayList<>(roleList.size());
        for (Role role : roleList) {
            RoleDto dto = new RoleDto();
            dto.setRoleId(role.getId());
            dto.setRoleName(role.getRoleName());
            dtoList.add(dto);
        }
        return dtoList;
    }

    @Override
    public List<PermissionsDto> findPermissionsByRole(List<RoleDto> roleList) {
        try {
            Example example = new Example(RoleMenu.class);
            example.and().andIn("roleId", ObjectUtil.getFieldList(roleList, "roleId", Integer.class));
            List<RoleMenu> roleMenuList = roleMenuMapper.selectByExample(example);
            String menuIds = ObjectUtil.getFieldStr(roleMenuList, "menuId");
            List<Menu> menuList = menuService.findByIds(menuIds);
            return getPermissionsDtoList(menuList);
        } catch (NoSuchFieldException e) {
            return null;
        }
    }

    private List<PermissionsDto> getPermissionsDtoList(List<Menu> menuList) {
        List<PermissionsDto> dtoList = new ArrayList<>(menuList.size());
        for (Menu menu : menuList) {
            PermissionsDto dto = new PermissionsDto();
            dto.setId(menu.getId());
            dto.setUrl(menu.getUrl());
            dto.setPermissionsString(menu.getPermission());
            dtoList.add(dto);
        }
        return dtoList;
    }

    @Override
    public void setRoleAndPermissions(PrincipalUser user) throws NoSuchFieldException {
        List<RoleDto> roleList = findRoleByUserId(user.getId());
        List<PermissionsDto> permissionsList = findPermissionsByRole(roleList);
        HashSet<String> roleSet = new HashSet<>(ObjectUtil.getFieldList(roleList, "roleName", String.class));
        HashSet<String> urlSet = new HashSet<>(ObjectUtil.getFieldList(permissionsList, "url", String.class));
        urlSet.add("/logout");
        urlSet.add("/logout2");
        user.setRoleSet(roleSet);
        user.setUrlSet(urlSet);
    }
}
